/*
 * Copyright (C) 2016, apexes.net. All rights reserved.
 * 
 *        http://www.apexes.net
 * 
 */
package net.apexes.wsonrpc.demo.server;

import net.apexes.wsonrpc.core.GZIPBinaryWrapper;
import net.apexes.wsonrpc.core.WsonrpcConfig;
import net.apexes.wsonrpc.core.WsonrpcConfigBuilder;
import net.apexes.wsonrpc.core.WsonrpcRemote;
import net.apexes.wsonrpc.demo.api.DemoService;
import net.apexes.wsonrpc.demo.api.RegisterService;
import net.apexes.wsonrpc.demo.server.service.DemoServiceImpl;
import net.apexes.wsonrpc.demo.server.service.RegisterServiceImpl;
import net.apexes.wsonrpc.demo.util.SimpleWsonrpcLogger;
import net.apexes.wsonrpc.json.support.jackson.JacksonImplementor;
import net.apexes.wsonrpc.server.WsonrpcServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * 
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 */
public class DemoWsonrpcServer {
    private static final Logger LOG = LoggerFactory.getLogger(DemoWsonrpcServer.class);

    static {
        SLF4JBridgeHandler.install();
    }
    
    public static void main(String[] args) throws Exception {
        new DemoWsonrpcServer().launchVertxServer();
    }

    protected void launchJwsServer() throws Exception {
        launch(new JwsDemoWsonrpcServerImpl());
    }

    protected void launchTyrusServer() throws Exception {
        launch(new TyrusDemoWsonrpcServerImpl());
    }

    protected void launchNettyServer() throws Exception {
        launch(new NettyDemoWsonrpcServerImpl());
    }

    protected void launchVertxServer() throws Exception {
        launch(new VertxDemoServerImpl());
    }

    protected void launch(DemoServer server) throws Exception {
        runServer(server);
    }

    protected WsonrpcConfigBuilder createWsonrpcConfigBuilder() {
        return WsonrpcConfigBuilder.create()
                .json(new JacksonImplementor())
                .wrapper(new GZIPBinaryWrapper())
                .logger(new SimpleWsonrpcLogger());
    }
    
    protected void runServer(DemoServer demoServer) throws Exception {
        WsonrpcConfig config = createWsonrpcConfigBuilder().build();
        WsonrpcServer serverBase = demoServer.create(8080, "/wsonrpc", config);
        if (serverBase != null) {
            setupServer(serverBase);
        }
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            System.out.print(">");
            String command = reader.readLine();
            if (command.isEmpty()) {
                continue;
            }
            if ("startup".equalsIgnoreCase(command)) {
                demoServer.startup();
            } else if ("shutdown".equalsIgnoreCase(command)) {
                demoServer.shutdown();
                LOG.info("Server is shutdown");
                System.exit(0);
                break;
            } else if (command.startsWith("call ")) {
                String[] cmds = command.split(" ");
                demoServer.call(cmds[1]);
            } else if (command.startsWith("notice ")) {
                String[] cmds = command.split(" ");
                if (cmds.length >= 3) {
                    demoServer.notice(cmds[1], cmds[2]);
                } else {
                    demoServer.notice(cmds[1], null);
                }
            } else if (command.startsWith("disconnect")) {
                String[] cmds = command.split(" ");
                if (cmds.length > 1) {
                    WsonrpcRemote remote = AbstractDemoWsonrpcServer.findRemote(cmds[1]);
                    if (remote != null) {
                        remote.disconnect();
                    }
                }
            } else if ("ping".equals(command)) {
                demoServer.ping(null);
            } else if (command.startsWith("ping ")) {
                String[] cmds = command.split(" ");
                if (cmds.length > 1) {
                    demoServer.ping(cmds[1]);
                } else {
                    demoServer.ping(null);
                }
            }
        }
    }
    
    protected void setupServer(WsonrpcServer serverBase) {
        serverBase.setWsonrpcOpenListener(session -> LOG.info("sessionId={}", session.getId()));
        serverBase.setWsonrpcCloseListener(sessionId -> {
            LOG.info("onClose: sessionId={}", sessionId);
            DemoOnlineClientHolder.unregister(sessionId);
        });
        serverBase.setWsonrpcMessageListener((sessionId, bytes) -> LOG.info("onMessage: sessionId={}, length={}", sessionId, bytes.length));
        bindService(serverBase);
    }

    protected void bindService(WsonrpcServer serverBase) {
        // 注册服务供Client调用
        serverBase.getServiceRegistry().allSimpleName()
                .bind(DemoService.class).toInstance(new DemoServiceImpl())
                .bind(RegisterService.class).toInstance(new RegisterServiceImpl());
    }

}
